#include <sstream>
#include <assert.h>
#include "../Include/HttpRequestParam.h"
using namespace std;

CHttpRequestParam::CHttpRequestParam()
{
    m_strUri = "/";
    m_strMethod = "GET";
    m_nTimeout = 10000;
    m_callback.OnSuccess = [](const CHttpResMessage&) {};
    m_callback.OnFailed = [](Int32, const char*) {};
    m_callback.OnCompleted = []() {};
}

CHttpRequestParam::~CHttpRequestParam()
{
}

void CHttpRequestParam::SetServer(const CSocketAddr &addr)
{
    m_addr = addr;
    m_mpHeaders["Host"] = addr.GetAddrString();
}

void CHttpRequestParam::SetUri(const string &strUri)
{
    m_strUri = strUri;
}

void CHttpRequestParam::SetMethed(const string &strMethod)
{
    m_strMethod = strMethod;
}

void CHttpRequestParam::AddHeader(const string &strField, const string &strValue)
{
    m_mpHeaders[strField] = strValue;
}

void CHttpRequestParam::AddHeader(const string &strField, Int32 nValue)
{
    m_mpHeaders[strField] = STR::NumberToString(nValue);
}

void CHttpRequestParam::AddHeader(const string &strField, Int64 lValue)
{
    m_mpHeaders[strField] = STR::NumberToString(lValue);
}

void CHttpRequestParam::SetBody(const string &strBody, const string &strContentType)
{
    m_strBody.assign(strBody);
    m_mpHeaders["Content-Type"] = strContentType;
    m_mpHeaders["Content-Length"] = STR::NumberToString(strBody.length());
}

void CHttpRequestParam::SetCallback(const HttpRequestCallback &callback)
{
    if (callback.OnSuccess != nullptr)
    {
        m_callback.OnSuccess = callback.OnSuccess;
    }
    if (callback.OnFailed != nullptr)
    {
        m_callback.OnFailed = callback.OnFailed;
    }
    if (callback.OnCompleted != nullptr)
    {
        m_callback.OnCompleted = callback.OnCompleted;
    }
}

void CHttpRequestParam::SetTimeout(int nTimeout)
{
    assert(nTimeout > 0);
    m_nTimeout = nTimeout;
}

const string CHttpRequestParam::GetRequest() const
{
    ostringstream oss;
    oss << m_strMethod << " " << m_strUri << " HTTP/1.1\r\n";
    for (const auto &it : m_mpHeaders)
    {
        oss << it.first << ": " << it.second << "\r\n";
    }
    if (m_strBody.empty())
    {
        oss << "Content-Length: 0\r\n";
    }

    oss << "\r\n";
    oss << m_strBody;

    return oss.str();
}
